#include "StdAfx.h"
#include "SObjectModel.h"

// SObjectItem ////////////////////////////////////////////////////////////////

//
SObjectItem::SObjectItem()
	:m_parentItem(NULL)
{
}

//
int SObjectItem::childCount() const
{
	return m_childItems.count();
}

//
int SObjectItem::columnCount() const
{
	return 2;
}

//
int SObjectItem::childRow() const
{
	if (m_parentItem) {
		//return m_parentItem->m_childItems.indexOf(const_cast<VNavItem*>(this));

		for (int i = 0; i < m_parentItem->m_childItems.count(); ++i) {
			if (m_parentItem->m_childItems[i] == this) {
				return i;
			}
		}
	}

	return -1;
}

//
void SObjectItem::appendChild(const SObjectItemPtr &insItem)
{
	insItem->m_parentItem = this;
	m_childItems.append(insItem);
}

//
void SObjectItem::appendChild(const QList<SObjectItemPtr> &insItems)
{
	foreach (SObjectItemPtr insItem,insItems) {
		appendChild(insItem);
	}
}

//
void SObjectItem::removeChildren()
{
	m_childItems.clear();
}

//
QVariant SObjectItem::data(int column) const
{
/*
	if (column < 0 || column >= columnCount())
		return QVariant();
*/
	switch (column) {
		case 0: return m_object->id();
		case 1: return m_object->displayName();
	}
	return QVariant();
}

// SObjectModel ///////////////////////////////////////////////////////////////

//
SObjectModel::SObjectModel(QObject *parent)
	:QAbstractItemModel(parent)
	,m_rootItem(NULL)
{
}

//
SObjectModel::~SObjectModel()
{
}

//
void SObjectModel::setRootItem(const SObjectItemPtr &item)
{
	m_rootItem = item;
	reset();
}

//
SObjectItem *SObjectModel::itemFromIndex(const QModelIndex &index) const
{
	if (index.isValid()) {
		//VNavItem *item = qobject_cast<VNavItem*>( static_cast<VNavItem*>(itemIndex.internalPointer()) );
		//VNavItem *item = (VNavItem*)itemIndex.internalPointer();
		//SObjectItem *item = qobject_cast<VNavItem*>( (QObject*)itemIndex.internalPointer() );

		SObjectItem *item = (SObjectItem*)index.internalPointer();

		if (item) {
			return item;
		}
	}
	return m_rootItem.data();
}

//
QVariant SObjectModel::headerData(int section,Qt::Orientation orientation,int role) const
{
	if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
		switch (section) {
			case 0: return "id";
			case 1: return "displayName";
		}
	}

	return QVariant();
}

//
QModelIndex SObjectModel::index(int row,int column,const QModelIndex &parent) const
{
	SObjectItem *parentItem = itemFromIndex(parent);
	if (parentItem->childCount() == 0) {
		return QModelIndex();
	}

	SObjectItem *childItem = parentItem->child(row);
	return createIndex(row,column,childItem);
}

//
QModelIndex SObjectModel::parent(const QModelIndex &index) const
{
	if (!index.isValid())
		return QModelIndex();

	SObjectItem *childItem = itemFromIndex(index);
	SObjectItem *parentItem = childItem->parent();

	if (!parentItem)
		return QModelIndex();

	return createIndex(parentItem->childRow(),0,parentItem);
}

//
Qt::ItemFlags SObjectModel::flags(const QModelIndex &index) const
{
	if (!index.isValid())
		return 0;

	return /*Qt::ItemIsEditable |*/ Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

//
int SObjectModel::rowCount(const QModelIndex &parent) const
{
	SObjectItem *parentItem = itemFromIndex(parent);
	return parentItem->childCount();
}

//
int SObjectModel::columnCount(const QModelIndex &parent) const
{
	return m_rootItem->columnCount();
}

//
QVariant SObjectModel::data(const QModelIndex &index,int role) const
{
	if (!index.isValid())
		return QVariant();

	switch (role)
	{
		case Qt::DisplayRole: 
		case Qt::EditRole: 
		{
			SObjectItem *item = itemFromIndex(index);
			QVariant value = item->data(index.column());

			return value.isNull() ? QVariant("<null>") : value;
		}
		break;
	
		case Qt::TextColorRole:
		{
			SObjectItem *item = itemFromIndex(index);
			QVariant value = item->data(index.column());

			if (value.isNull())
				return QColor(255,0,0);
		}
		break;

		case Qt::FontRole:
		{
			SObjectItem *item = itemFromIndex(index);
			
			//if (VNavItemHeader::displayName == index.column() && item->childCount() > 0) {
			if (item->object()->isGroupObjects()) {
				QFont font;
					font.setPointSize(font.pointSize()+3);
					font.setItalic(true);
					font.setBold(true);
				return font;
			}
		}
		break;
		
		case Qt::DecorationRole: {
			//return m_folderIcon;
			//return QVariant();
		}
		break;
	}
	
	return QVariant();
}

// SObjectModelLoader /////////////////////////////////////////////////////////

//
SObjectModelLoader::SObjectModelLoader(const SGroupObjectsGlobalPtr &globalGroup,SObjectModel *model)
	:m_globalGroup(globalGroup)
	,m_model(model)
{
	m_model->setRootItem(SObjectItemPtr());
}
/*
//
void SObjectModelLoader::startGroupObjects(SObject *p)
{
	if (!m_parentItems.count()) {
		m_parentItems.push(m_model->invisibleRootItem());
		return;
	}

	QStandardItem *item = factoryItem(p);
		item->setBackground(QBrush(QColor(0,200,0,20)));
		QFont font = item->font();
			font.setItalic(true);
			font.setBold(true);
			font.setPointSize(font.pointSize()+4);
		item->setFont(font);

	m_parentItems.top()->appendRow(item);
	m_parentItems.push(item);
}

//
void SObjectModelLoader::endGroupObjects(SObject *p) 
{
	m_parentItems.pop();
}

//
void SObjectModelLoader::visitObject(SObject *p)
{
	if (!m_parentItems.count()) {
		return;
	}

	if (!p->isGroupObjects()) {
		QStandardItem *item = factoryItem(p);
		m_parentItems.top()->appendRow(item);

		int ccc = item->column();
		int rrr = item->row();
		item=item;
	}
}
*/
//
SObjectItemPtr SObjectModelLoader::factoryItem(SObject *p) const
{
	SObjectPtr o = m_globalGroup->findByPtr(p);
	if (!o) {
		return SObjectItemPtr();
	}

	SObjectItemPtr item = SObjectItemPtr(new SObjectItem);
		item->setObject(o);
	return item;
}
